#include "plugin.h"

#include <string.h>

// ----------------------------------------------------------------------------
XCALL_(LWInstance) BWcoCreate(void *priv, LWItemID item, LWError *err)
{
    BWcoInstanceData* instance = NULL;

    instance = calloc(1, sizeof(BWcoInstanceData));
    if (instance)
    {
        instance->globalFunc = priv;
        instance->itemID = item;

        instance->renderSettings.partSize = 0.015f;
        instance->renderSettings.partDensity = 10;
        instance->renderSettings.colorVariation = 0.07f;
        instance->renderSettings.colorDisplacement = 0.0f;
        instance->renderSettings.fixedPartPlacement = FALSE;
        instance->renderSettings.alignParticles = FALSE;
        instance->renderSettings.backFaceCulling = TRUE;

        strcpy_s(instance->renderSettings.brushFilename, 
            MAX_FILENAME_LENGTH, DEFAULT_BRUSH);

    }
    else
        *err = "Could not allocate memory for custom object instance data!";
    
    AddToGlobalList(instance);

    return instance;
}

// ----------------------------------------------------------------------------
XCALL_(void) BWcoDestroy(BWcoInstanceData *instance)
{
    // We do not free the memory of the instance -> this is done in Shutdown. 
    // This makes it simpler to handle the global instance list.    

    if (instance)
        RemoveFromGlobalList(instance->itemID);
}

// ----------------------------------------------------------------------------
XCALL_(LWError) BWcoCopy(BWcoInstanceData *to, BWcoInstanceData *from)
{
    LWItemID itemID;

    itemID = to->itemID;
    *to = *from;
    to->itemID = itemID;

    return NULL;
}

// ----------------------------------------------------------------------------
XCALL_(const char *) BWcoDescribe(BWcoInstanceData *instance) 
{ 
    return "BrushWave - Painterly Rendering (Custom Object)"; 
}

// ----------------------------------------------------------------------------
XCALL_(const LWItemID*) BWcoUseItems(BWInstanceData *instance) 
{ 
    return NULL; 
}

// ----------------------------------------------------------------------------
XCALL_(void) BWcoChangeID(BWcoInstanceData *instance, const LWItemID *ids) 
{ }

// ----------------------------------------------------------------------------
XCALL_(LWError) BWcoInit(BWcoInstanceData *instance, int mode) 
{ 
    return NULL; 
}

// ----------------------------------------------------------------------------
XCALL_(void) BWcoCleanup(BWcoInstanceData *instance) 
{ }

// ----------------------------------------------------------------------------
XCALL_(LWError) BWcoNewTime(BWcoInstanceData *instance, LWFrame fr, LWTime t) 
{ 
    return NULL; 
}

// ----------------------------------------------------------------------------
XCALL_(unsigned int) BWcoFlags(BWcoInstanceData *instance) 
{ 
    return 0; 
}

// ----------------------------------------------------------------------------
XCALL_(void) BWcoEvaluate(BWcoInstanceData *instance, const LWCustomObjAccess *access)
{
    // TODO: draw representational image here    
}

// ----------------------------------------------------------------------------
XCALL_(int) BWcoActivate (long version, GlobalFunc *globalFunc, 
                          LWCustomObjHandler *local, void *serverData)
{
    if (version != LWCUSTOMOBJ_VERSION) return AFUNC_BADVERSION;

    local->inst->create  = BWcoCreate;
    local->inst->destroy = BWcoDestroy;
    local->inst->load    = BWcoLoad; // -> see file_io.c
    local->inst->save    = BWcoSave; // -> see file_io.c
    local->inst->copy    = BWcoCopy;
    local->inst->descln  = BWcoDescribe;
    local->inst->priv    = globalFunc; // save global func to be able to access
                                       // it in the create function

    if (local->item) 
    {
        local->item->useItems = BWcoUseItems;
        local->item->changeID = BWcoChangeID;
    }

    if (local->rend) 
    {
        local->rend->init    = BWcoInit;
        local->rend->cleanup = BWcoCleanup;
        local->rend->newTime = BWcoNewTime;
    }

    local->evaluate = BWcoEvaluate;
    local->flags    = BWcoFlags;

    return AFUNC_OK;
}

// ----------------------------------------------------------------------------
XCALL_(int) BWcoUiActivate (long version, GlobalFunc *globalFunc, 
                            LWInterface *ui, void *serverData)
{   
    BWcoInstanceData* instance;
    
    if (version != LWINTERFACE_VERSION) return (AFUNC_BADVERSION);

    instance = (BWcoInstanceData*) ui->inst;

    ui->panel   = BWcoCreatePanel(instance);
    ui->options = NULL;
    ui->command = NULL;

    return AFUNC_OK;
}
